#region License

// This file is part of Grawlix.
// 
// Grawlix is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
// Grawlix is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License along with Grawlix.  If not, see
// <http://www.gnu.org/licenses/>.

#endregion

using System;
using System.Runtime.Serialization;

namespace Grawlix.Services
{
	/// <summary>
	/// The serialization context used when serializing game kernel
	/// data for persistence.
	/// </summary>
	public class GameKernelStreamingContext
	{
		/// <summary>
		/// The serialization kernel.
		/// </summary>
		private readonly IGameKernel _kernel;

		/// <summary>
		/// Sets required data for the context information.
		/// </summary>
		/// <param name="kernel">The kernel to use to access services.
		/// </param>
		/// <exception cref="ArgumentNullException"><c>kernel</c> is
		/// null.</exception>
		public GameKernelStreamingContext(IGameKernel kernel)
		{
			if (kernel == null)
				throw new ArgumentNullException("kernel");
			_kernel = kernel;
		}

		/// <summary>
		/// Gets the kernel to use to access services.
		/// </summary>
		/// <value>The kernel to use to access services.</value>
		public IGameKernel Kernel
		{
			get { return _kernel; }
		}

		/// <summary>
		/// Gets the kernel of the given streaming context, assuming
		/// the presence of a <see cref="GameKernelStreamingContext"/>.
		/// Throws a proper exception otherwise.
		/// </summary>
		/// <param name="context">The given context.</param>
		/// <returns>The <see cref="IGameKernel"/> of the 
		/// <see cref="GameKernelStreamingContext"/>.</returns>
		/// <exception cref="SerializationException">Unable to
		/// serialize or deserialize persistent data that relies on a
		/// game kernel without a context that game kernel.</exception>
		public static IGameKernel GetContextKernel(
			StreamingContext context)
		{
			var streamingContext =
				context.Context as GameKernelStreamingContext;
			if (streamingContext == null)
			{
				throw new SerializationException(
					"Unable to serialize or deserialize " +
					"persistent data that " +
					"relies on a game kernel without a context that " +
					"game kernel.");
			}
			return streamingContext.Kernel;
		}

		/// <summary>
		/// Gets the kernel of the given streaming context, assuming
		/// the presence of a <see cref="GameKernelStreamingContext"/>
		/// or returns null.
		/// </summary>
		/// <param name="context">The given context.</param>
		/// <returns>The <see cref="IGameKernel"/> of the 
		/// <see cref="GameKernelStreamingContext"/>.</returns>
		public static IGameKernel TryGetContextKernel(
			StreamingContext context)
		{
			var streamingContext =
				context.Context as GameKernelStreamingContext;
			if (streamingContext == null)
				return null;
			return streamingContext.Kernel;
		}
	}
}